<template>
  <div class="flex-col">
    <n-form
      ref="$form"
      :model="model"
      label-placement="left"
      label-align="right"
      require-mark-placement="left"
      :label-width="132"
    >
      <n-form-item label="测试方法" path="testMethodId">
        <AsyncSelect
          v-model:value="model.testMethodId"
          :options="getMethodsList"
          label-key="testMethodName"
          value-key="id"
          :disabled="true"
        />
      </n-form-item>
      <n-form-item v-if="type === 'static'" label="基准数据集" path="datasetIds">
        <AsyncSelect
          v-model:value="model.datasetIds"
          :options="getDataSetList"
          label-key="datasetName"
          value-key="id"
          :disabled="true"
        />
      </n-form-item>
      <n-form-item :label="type === 'static' ? '数据处理进度' : '任务准备进度'">
        <MyProgress
          :color="statusResult.color"
          :percentage="progress"
          :text="statusResult.text"
          :gradient="statusResult.gradient"
        />
      </n-form-item>
      <n-form-item :label="type === 'static' ? '测试数据集' : '测试场景信息'" path="info">
        <n-input v-model:value="model.info" :disabled="true" />
      </n-form-item>
      <n-form-item label="执行反馈">
        <div class="my-card">
          <n-scrollbar ref="$feedback" :style="{ height: `${feebackHeight}px` }">
            <div v-for="(item, index) in feedbackList" :key="index">{{ item }}</div>
          </n-scrollbar>
        </div>
      </n-form-item>
    </n-form>
    <Teleport v-if="isMounted" to="#step-control">
      <div class="my-btn-group mt-32">
        <n-button :color="appStore.buttonColor" :disabled="!enable" @click="handleNext">
          启动测试
        </n-button>
      </div>
    </Teleport>
  </div>
</template>
<script setup lang="jsx">
import { useAppStore } from '@/store'
import { useMounted } from '@/hooks/useMounted'
import * as testRecordApi from '@/api/testRecord'
import * as testObjectApi from '@/api/testObject'
import * as dataSetApi from '@/api/dataSet'
import { objectMergLeft } from '@/utils/common'
import { useMqttStore } from '@/store'
import { lightColorMap, deepColorMap } from '@/enum/process'
import { specialSimulatorValues } from '@/enum/simulator'
defineOptions({
  name: 'StartTest',
})
const appStore = useAppStore()
const emits = defineEmits(['next', 'prev'])
const props = defineProps({
  id: {
    type: String,
    default: null,
  },
})
const { isMounted } = useMounted()
const model = ref({
  testMethodId: null,
  datasetIds: null,
  info: null,
})
function getMethodsList() {
  return testObjectApi.methodsList()
}
function getDataSetList() {
  return dataSetApi.listAll()
}

const type = ref('static')
const special = ref(false)
async function getInfo() {
  const { data } = await testRecordApi.info(props.id)
  model.value = objectMergLeft(model.value, data)
  type.value = data.testModeId === '2' ? 'static' : 'dynamic'
  special.value = specialSimulatorValues.includes(data.simulator)
  if (special.value) {
    // qt与启明星 特殊直接满进度
    enable.value = true
    progress.value = 100
    feedbackList.value = ['暂不支持']
  } else {
    // 轮询状态
    timer = setInterval(() => {
      getProgressInfo()
    }, 1000)
    // 开启订阅
    getHistoryFeedbackList().then(() => {
      mqttStore.subscribe({
        topic: currentTopic.value,
        callback(_, msg) {
          feedbackList.value.push(msg)
          nextTick(() => {
            $feedback.value.scrollTo({ top: feebackHeight.value })
          })
        },
      })
    })
  }
}

// 轮询查取进度
let timer = null
const progress = ref(0)
const enable = defineModel('enable', {
  type: Boolean,
  default: false,
})
const statusResult = computed(() => {
  if (enable.value) {
    return {
      text: '准备完成',
      ...(appStore.isDeep ? deepColorMap.complete : lightColorMap.complete),
    }
  } else {
    return {
      text: '处理中',
      ...(appStore.isDeep ? deepColorMap.processing : lightColorMap.processing),
    }
  }
})
function getProgressInfo() {
  testRecordApi
    .progressInfo(props.id)
    .then((res) => {
      const last = res.data.testProgress.at(-1)
      progress.value = last['progress']
      if (last['progress'] === 100) {
        enable.value = true
        clearInterval(timer)
        timer = null
      }
    })
    .catch(() => {
      clearInterval(timer)
      timer = null
    })
}

// 订阅数据/任务准备执行反馈
const $feedback = ref(null)
const feebackHeight = ref(220)
const feedbackList = ref([])
const mqttStore = useMqttStore()
const currentTopic = computed(() => `preparation-${props.id}`)
async function getHistoryFeedbackList() {
  const { data } = await testObjectApi.executeFeedbackList(props.id)
  feedbackList.value = data.map((item) => item.information)
}

onBeforeMount(() => {
  getInfo()
})
onBeforeUnmount(() => {
  // 取消定时器
  if (timer) {
    clearInterval(timer)
    timer = null
  }
  // 取消订阅
  mqttStore.unsubscribe(currentTopic.value)
})

function handleNext() {
  if (special.value) {
    testRecordApi
      .startTestSpecial(props.id)
      .then(() => {
        $message.success('启动测试成功!')
        emits('next')
      })
      .catch(() => {
        $message.error('启动测试失败!')
      })
  } else {
    testRecordApi
      .startTest(props.id)
      .then(() => {
        $message.success('启动测试成功!')
        emits('next')
      })
      .catch(() => {
        $message.error('启动测试失败!')
      })
  }
}
</script>
<style lang="scss" scoped></style>
